using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ERP.RepositoryManage;
using ERP.RepositoryManage.Dtos;
using ERP.ERPModels.RepositoryManage;
using ERP.ERPModels.Production.ProductionManagement;
using ERP.ERPModels.Production.MasterData;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.ObjectMapping;

namespace ERP.Application.RepositoryManage
{
    /// <summary>
    /// 装箱管理服务
    /// </summary>
    public class PackingService : ApplicationService, IPackingService
    {
        private readonly IRepository<Packing, int> _packingRepository;
        private readonly IRepository<PackingDetail, int> _packingDetailRepository;
        private readonly IRepository<ProductionWorkOrders, int> _workOrderRepository;
        private readonly IRepository<Customers, int> _customerRepository;

        public PackingService(
            IRepository<Packing, int> packingRepository,
            IRepository<PackingDetail, int> packingDetailRepository,
            IRepository<ProductionWorkOrders, int> workOrderRepository,
            IRepository<Customers, int> customerRepository)
        {
            _packingRepository = packingRepository;
            _packingDetailRepository = packingDetailRepository;
            _workOrderRepository = workOrderRepository;
            _customerRepository = customerRepository;
        }

        /// <summary>
        /// 获取装箱树形列表
        /// </summary>
        public async Task<List<PackingDto>> GetTreeListAsync(GetPackingInputDto input)
        {
            try
            {
                // 获取所有装箱数据
                var query = await _packingRepository.GetQueryableAsync();
                
                // 应用筛选条件
                if (!string.IsNullOrEmpty(input?.PackingCode))
                {
                    query = query.Where(x => x.PackingCode.Contains(input.PackingCode));
                }
                if (!string.IsNullOrEmpty(input?.CustomerCode))
                {
                    query = query.Where(x => x.CustomerCode.Contains(input.CustomerCode));
                }
                if (!string.IsNullOrEmpty(input?.State))
                {
                    query = query.Where(x => x.State == input.State);
                }
                if (input?.PackingDateStart.HasValue == true)
                {
                    query = query.Where(x => x.PackingDate.HasValue && x.PackingDate.Value.Date >= input.PackingDateStart.Value.Date);
                }
                if (input?.PackingDateEnd.HasValue == true)
                {
                    query = query.Where(x => x.PackingDate.HasValue && x.PackingDate.Value.Date <= input.PackingDateEnd.Value.Date);
                }
                
                // 获取所有符合条件的装箱数据
                var packings = query.ToList();
                
                System.Diagnostics.Debug.WriteLine($"查询到装箱数据数量: {packings.Count}");
                
                // 转换为DTO
                var result = ObjectMapper.Map<List<Packing>, List<PackingDto>>(packings);
                
                // 输出调试信息
                System.Diagnostics.Debug.WriteLine($"返回所有装箱数据数量: {result.Count}");
                var rootCount = result.Count(x => x.ParentId == null || x.ParentId == 0);
                var childCount = result.Count(x => x.ParentId != null && x.ParentId > 0);
                System.Diagnostics.Debug.WriteLine($"根节点数量: {rootCount}, 子节点数量: {childCount}");

                // 返回所有数据，包括父箱和子箱
                return result;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"GetTreeListAsync异常: {ex.Message}");
                System.Diagnostics.Debug.WriteLine($"异常堆栈: {ex.StackTrace}");
                throw;
            }
        }

        /// <summary>
        /// 获取装箱分页列表
        /// </summary>
        public async Task<PagedResultDto<PackingDto>> GetListAsync(GetPackingInputDto input)
        {
            var query = await _packingRepository.GetQueryableAsync();
            
            // 如果指定了ParentId，则查询子箱列表
            if (input.ParentId.HasValue)
            {
                query = query.Where(x => x.ParentId == input.ParentId.Value);
            }
            else
            {
                // 默认查询顶级装箱（ParentId为null或0）
                query = query.Where(x => x.ParentId == null || x.ParentId == 0);
            }
            
            // 应用筛选条件
            if (!string.IsNullOrEmpty(input.PackingCode))
            {
                query = query.Where(x => x.PackingCode.Contains(input.PackingCode));
            }
            if (!string.IsNullOrEmpty(input.CustomerCode))
            {
                query = query.Where(x => x.CustomerCode.Contains(input.CustomerCode));
            }
            if (!string.IsNullOrEmpty(input.State))
            {
                query = query.Where(x => x.State == input.State);
            }
            if (input.PackingDateStart.HasValue)
            {
                query = query.Where(x => x.PackingDate.HasValue && x.PackingDate.Value.Date >= input.PackingDateStart.Value.Date);
            }
            if (input.PackingDateEnd.HasValue)
            {
                query = query.Where(x => x.PackingDate.HasValue && x.PackingDate.Value.Date <= input.PackingDateEnd.Value.Date);
            }

            var totalCount = query.Count();

            var packings = query
                .Skip(input.SkipCount)
                .Take(input.MaxResultCount)
                .OrderBy(x => x.Id)
                .ToList();

            var result = ObjectMapper.Map<List<Packing>, List<PackingDto>>(packings);
            
            // 获取装箱明细
            var packingIds = packings.Select(x => x.Id).ToList();
            var details = await _packingDetailRepository.GetListAsync(x => packingIds.Contains(x.PackingId));
            
            foreach (var item in result)
            {
                var packingDetails = details.Where(x => x.PackingId == item.Id).ToList();
                item.Details = ObjectMapper.Map<List<PackingDetail>, List<PackingDetailDto>>(packingDetails);
            }

            return new PagedResultDto<PackingDto>(totalCount, result);
        }

        /// <summary>
        /// 获取装箱详情
        /// </summary>
        public async Task<PackingDto> GetAsync(int id)
        {
            var packing = await _packingRepository.GetAsync(id);
            var result = ObjectMapper.Map<Packing, PackingDto>(packing);
             
            // 获取装箱明细
            var details = await _packingDetailRepository.GetListAsync(x => x.PackingId == id);
            result.Details = ObjectMapper.Map<List<PackingDetail>, List<PackingDetailDto>>(details);
            
            // 获取子箱
            var children = await _packingRepository.GetListAsync(x => x.ParentId == id);
            result.Children = ObjectMapper.Map<List<Packing>, List<PackingDto>>(children);

            return result;
        }

        /// <summary>
        /// 创建装箱
        /// </summary>
        public async Task<PackingDto> CreateAsync(CreatePackingDto input)
        {
            var packing = ObjectMapper.Map<CreatePackingDto, Packing>(input);
            
            // 生成装箱单编号
            packing.PackingCode = await GeneratePackingCodeAsync();
            
            // 设置默认状态为草稿
            packing.State = "0";
            
            var result = await _packingRepository.InsertAsync(packing);
            return ObjectMapper.Map<Packing, PackingDto>(result);
        }

        /// <summary>
        /// 更新装箱
        /// </summary>
        public async Task<PackingDto> UpdateAsync(int id, UpdatePackingDto input)
        {
            var packing = await _packingRepository.GetAsync(id);
            ObjectMapper.Map(input, packing);
            
            var result = await _packingRepository.UpdateAsync(packing);
            return ObjectMapper.Map<Packing, PackingDto>(result);
        }

        /// <summary>
        /// 删除装箱
        /// </summary>
        public async Task DeleteAsync(int id)
        {
            // 删除装箱明细
            var details = await _packingDetailRepository.GetListAsync(x => x.PackingId == id);
            foreach (var detail in details)
            {
                await _packingDetailRepository.DeleteAsync(detail);
            }
            
            // 删除子箱
            var children = await _packingRepository.GetListAsync(x => x.ParentId == id);
            foreach (var child in children)
            {
                await DeleteAsync(child.Id);
            }
            
            // 删除装箱
            await _packingRepository.DeleteAsync(id);
        }

        /// <summary>
        /// 添加子箱
        /// </summary>
        public async Task<PackingDto> AddSubPackingAsync(int parentId, int subPackingId)
        {
            var childPacking = await _packingRepository.GetAsync(subPackingId);
            childPacking.ParentId = parentId;
            
            var result = await _packingRepository.UpdateAsync(childPacking);
            return ObjectMapper.Map<Packing, PackingDto>(result);
        }

        /// <summary>
        /// 获取可选择的装箱列表（父级ID为0的装箱）
        /// </summary>
        public async Task<PagedResultDto<PackingDto>> GetParentPackingSelectListAsync(GetPackingInputDto input)
        {
            var query = await _packingRepository.GetQueryableAsync();
            
            // 只获取父级ID为0或null的装箱
            query = query.Where(x => x.ParentId == null || x.ParentId == 0);
            
            // 应用筛选条件
            if (!string.IsNullOrEmpty(input.PackingCode))
            {
                query = query.Where(x => x.PackingCode.Contains(input.PackingCode));
            }
            
            var totalCount = query.Count();
            
            var packings = query
                .Skip(input.SkipCount)
                .Take(input.MaxResultCount)
                .OrderBy(x => x.Id)
                .ToList();
                
            var result = ObjectMapper.Map<List<Packing>, List<PackingDto>>(packings);
            return new PagedResultDto<PackingDto>(totalCount, result);
        }

        /// <summary>
        /// 获取装箱明细列表
        /// </summary>
        public async Task<List<PackingDetailDto>> GetPackingDetailsAsync(int packingId)
        {
            var details = await _packingDetailRepository.GetListAsync(x => x.PackingId == packingId);
            return ObjectMapper.Map<List<PackingDetail>, List<PackingDetailDto>>(details);
        }

        /// <summary>
        /// 添加装箱明细
        /// </summary>
        public async Task<PackingDetailDto> CreatePackingDetailAsync(CreatePackingDetailDto input)
        {
            var detail = ObjectMapper.Map<CreatePackingDetailDto, PackingDetail>(input);
            var result = await _packingDetailRepository.InsertAsync(detail);
            return ObjectMapper.Map<PackingDetail, PackingDetailDto>(result);
        }

        /// <summary>
        /// 删除装箱明细
        /// </summary>
        public async Task DeletePackingDetailAsync(int detailId)
        {
            await _packingDetailRepository.DeleteAsync(detailId);
        }

        /// <summary>
        /// 获取装箱明细详情
        /// </summary>
        public async Task<PackingDetailDto> GetPackingDetailAsync(int id)
        {
            var detail = await _packingDetailRepository.GetAsync(id);
            return ObjectMapper.Map<PackingDetail, PackingDetailDto>(detail);
        }

        /// <summary>
        /// 更新装箱明细
        /// </summary>
        public async Task<PackingDetailDto> UpdatePackingDetailAsync(int id, UpdatePackingDetailDto input)
        {
            var detail = await _packingDetailRepository.GetAsync(id);
            ObjectMapper.Map(input, detail);
            var result = await _packingDetailRepository.UpdateAsync(detail);
            return ObjectMapper.Map<PackingDetail, PackingDetailDto>(result);
        }

        /// <summary>
        /// 完成装箱（更新状态为已完成）
        /// </summary>
        public async Task CompletePacking(int id)
        {
            var packing = await _packingRepository.GetAsync(id);
            packing.State = "1"; // 已完成
            await _packingRepository.UpdateAsync(packing);
        }

        /// <summary>
        /// 获取生产工单选择列表
        /// </summary>
        public async Task<PagedResultDto<WorkOrderSelectDto>> GetWorkOrderSelectListAsync(GetWorkOrderSelectInputDto input)
        {
            var query = await _workOrderRepository.GetQueryableAsync();
            
            if (!string.IsNullOrEmpty(input.WorkOrderCode))
            {
                query = query.Where(x => x.OrderCode.Contains(input.WorkOrderCode));
            }
            if (!string.IsNullOrEmpty(input.ProductName))
            {
                query = query.Where(x => x.ProductName.Contains(input.ProductName));
            }

            var totalCount = query.Count();

            var workOrders = query
                .Skip(input.SkipCount)
                .Take(input.MaxResultCount)
                .OrderBy(x => x.Id)
                .ToList();

            var result = workOrders.Select(x => new WorkOrderSelectDto
            {
                Id = x.Id,
                WorkOrderCode = x.OrderCode ?? string.Empty,
                WorkOrderName = x.OrderName ?? string.Empty,
                SourceType = x.SourceType ?? string.Empty,
                ProductCode = x.ProductCode ?? string.Empty,
                ProductName = x.ProductName ?? string.Empty,
                Specification = x.Specification ?? string.Empty,
                Unit = x.Unit ?? string.Empty,
                Quantity = x.Quantity,
                RequiredDate = x.RequiredDate
            }).ToList();

            return new PagedResultDto<WorkOrderSelectDto>(totalCount, result);
        }

        /// <summary>
        /// 获取客户选择列表
        /// </summary>
        public async Task<PagedResultDto<CustomerSelectDto>> GetCustomerSelectListAsync(GetCustomerSelectInputDto input)
        {
            var query = await _customerRepository.GetQueryableAsync();
            
            if (!string.IsNullOrEmpty(input.CustomerCode))
            {
                query = query.Where(x => x.CustomerCode.Contains(input.CustomerCode));
            }
            if (!string.IsNullOrEmpty(input.CustomerName))
            {
                query = query.Where(x => x.CustomerName.Contains(input.CustomerName));
            }

            // 只显示有效客户
            query = query.Where(x => x.IsNo == 1);
            
            var totalCount = query.Count();

            var customers = query
                .Skip(input.SkipCount)
                .Take(input.MaxResultCount)
                .OrderBy(x => x.Id)
                .ToList();

            var result = customers.Select(x => new CustomerSelectDto
            {
                Id = x.Id,
                CustomerCode = x.CustomerCode ?? string.Empty,
                CustomerName = x.CustomerName ?? string.Empty,
                CustomerType = x.CustomerType ?? string.Empty,
                CustomerPhone = x.CustomerPhone ?? string.Empty,
                IsNo = x.IsNo
            }).ToList();

            return new PagedResultDto<CustomerSelectDto>(totalCount, result);
        }

        /// <summary>
        /// 生成装箱单编号
        /// </summary>
        public async Task<string> GeneratePackingCodeAsync()
        {
            var today = DateTime.Now.ToString("yyyyMMdd");
            var prefix = $"PK{today}";
            
            // 查询当天已生成的装箱单数量
            var count = await _packingRepository.CountAsync(x => x.PackingCode.StartsWith(prefix));
            
            // 生成序号，格式：PK20241220001
            var sequence = (count + 1).ToString("D3");
            return $"{prefix}{sequence}";
        }

        /// <summary>
        /// 移除子箱（将子箱的ParentId设为0）
        /// </summary>
        public async Task RemoveSubPackingAsync(int subPackingId)
        {
            var subPacking = await _packingRepository.GetAsync(subPackingId);
            subPacking.ParentId = 0;
            await _packingRepository.UpdateAsync(subPacking);
        }
    }
}
